package main

import (
	"flag"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"math/rand"
	"strings"
	"time"
	"zxs-micro/businesses/service"
	"zxs-micro/common/grpc/authserver/util"
	"zxs-micro/common/grpc/fwfxserver"
	"zxs-micro/common/log"
)

var (
	fConfig     = flag.String("config", "busi_config.yaml", "configuration file to load")
	fConfigPath = flag.String("config-path", "businesses/config", "directory containing additional *.yaml files")
)

var f *service.BusinessService

func main() {
	flag.Parse()
	viper.AddConfigPath(*fConfigPath)
	viper.AddConfigPath(".")
	viper.AddConfigPath("config")
	*fConfig = strings.Replace(*fConfig, ".yaml", "", 1)
	viper.SetConfigName(*fConfig)
	err := viper.ReadInConfig()
	log.Init(viper.GetString("log.level"), viper.GetString("log.format"))
	if err != nil {
		log.Log.Error("获取系统配置失败：", zap.String("err", err.Error()))
		panic("can not read config: " + err.Error())
	}

	go GenerateDemo1RestApi()

	f, err = service.GetNewBusinessService(new(Demo1))
	if err != nil {
		panic(err)
	}
	f.Start()
}

func GenerateDemo1RestApi() {
	r := gin.New()
	r.Use(gin.Logger())
	r.Use(gin.Recovery())
	g := r.Group("api")
	rand.Seed(time.Now().Unix())
	g.GET("login", func(c *gin.Context) {
		c1, err := util.GenerateAuthClient(f.GetLoginAddr())
		if err != nil {
			c.JSON(500, err.Error())
			return
		}
		result, err := c1.Login("un", "role")
		if err != nil {
			c.JSON(500, err.Error())
			return
		}
		c.JSON(200, result)
	})
	g.GET("exec1", func(c *gin.Context) {
		token := c.Request.Header.Get("bearer")
		params := make([][]byte, 0, 0)
		params = [][]byte{[]byte("123"), []byte("456")}
		var result []byte
		var err error
		//bs := utils.GenerateExecParamBytes(token, "demo2/", params)
		fx, err := fwfxserver.GenerateFwfxClients(f.GetFXaddr())
		if err != nil {
			c.JSON(500, err.Error())
			return
		}
		result, err = fx.ExecBusiness(params, token, "demo2/")
		if err != nil {
			c.JSON(500, err.Error())
			return
		}
		c.JSON(200, string(result))
	})
	g.GET("exec2", func(c *gin.Context) {
		token := c.Request.Header.Get("bearer")
		params := make([][]byte, 0, 0)
		params = [][]byte{[]byte("123"), []byte("456")}
		var result []byte
		var err error
		result, err = f.SelfExec(token, params)
		if err != nil {
			c.JSON(500, err.Error())
			return
		}
		c.JSON(200, string(result))
	})
	r.Run(":8080")
}

type Demo1 struct {
	auth *util.CommonAuthClient
}

//init方法会在初始化的时候被调用，此时可以进行部分初始化操作，没有则返回nil即可
func (d *Demo1) Init() (err error) {
	fmt.Println("初始化demo1")
	d.auth, err = util.GenerateAuthClient(f.GetLoginAddr())
	return
}

//提供内部服务调用的方法全部通过exec来进行转发
//TODO 此处不使用通用的exec，调用时使用方法名来进行反射调用(但是考虑到反射的缺陷，暂时不会进行修改)
func (d *Demo1) Exec(t string, p [][]byte) ([]byte, error) {

	m, err := d.auth.Token2Model(t)
	if err != nil {
		return nil, err
	}
	str1 := string(p[0])
	return []byte("from demo 1 :" + m.Account + ":" + str1), nil
}
